/**
 * 交叉类型是将多个类型合并为一个类型。
 * 这让我们可以把现有的多种类型叠加到一起成为一种类型，它包含了所需的所有类型的特性。
 */
class Person {
  name: string

  sex: string

  constructor(name: string, sex: string) {
    this.name = name;
    this.sex = sex;
  }
}

class Animal {
  name: string

  age: number

  constructor(name: string, age: number) {
    this.name = name;
    this.age = age;
  }
}

function extend<T, U>(first: T, second: U): T & U {
  const result = <T & U>{};
  Object.keys(first).forEach((element) => {
    (<any>result)[element] = (<any>first)[element];
  });
  Object.keys(second).forEach((element) => {
    if (!Object.prototype.hasOwnProperty.call(result, element)) {
      (<any>result)[element] = (<any>second)[element];
    }
  });
  return result;
}

const jim = extend(new Person('Jim', '男'), new Animal('猫', 2));
console.log(jim);
